package image;

import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.awt.image.Raster;

import deformedGrid.RectangelGridDeformation;
import stegru.tools.multiThreat.ParallelFor;
import grid.*;

/**
 * 
 * @author Stephan
 *
 */
public class DirectGridBasedImageDeformation extends RectangelGridDeformation{


	private BufferedImage image;

	public DirectGridBasedImageDeformation(BufferedImage image) {
		super(image.getWidth(), image.getHeight(), image.getWidth()-1, image.getHeight()-1, false);
		this.image = image;
	}

	public BufferedImage getImage() {
		// Memory access pattern 
		final int numGridPointsX = super.numGridPointsX;
		final int numGridPointsY = super.numGridPointsY;
		final BufferedImage srcImage = image;
		final BufferedImage off_Image =
				  new BufferedImage(numGridPointsX, numGridPointsY,
				                    BufferedImage.TYPE_INT_RGB);

		final Graphics2D g2 = off_Image.createGraphics();
		final double[][] changedGridPoints = getGrid().toArray();
		final double[][] gridPoints = getOriginalGrid().toArray();
		
		(new ParallelFor(0, numGridPointsX-1) {
			
			@Override
			protected void loop(int x) {
				for (int y = 0; y < numGridPointsY; y++) {
					synchronized (g2) {
						g2.setColor(new Color(srcImage.getRGB(round(gridPoints[x + numGridPointsX * y][0]), round(gridPoints[x + numGridPointsX * y][1]))));
						g2.fillRect(round(changedGridPoints[x + numGridPointsX * y][0]), round(changedGridPoints[x + numGridPointsX * y][1]), 1, 1);
					}
				}
				
			}
		}).calculate();
		off_Image.flush();
		System.out.println("drawed");
		return off_Image;
	}
	
	final static int round(double d){
		return (int) Math.round(d);
	}



}
